<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <div id="mountNode"></div>
    <script src="../build/g6.js"></script>
    <script>
      /**
       * 该案例演示如何自定义折线，有两种方式：
       * 1、继承line，复写getPath和getShapeStyle方法；
       * 2、复写draw方法。
       * by siogo 提供的 issue（https://github.com/antvis/g6/issues/814）
       *
       */
      G6.registerNode(
        'circleNode',
        {
          drawShape(cfg, group) {
            const keyShape = group.addShape('circle', {
              attrs: {
                x: 0,
                y: 0,
                r: 30,
                fill: '#87e8de',
              },
            });

            return keyShape;
          },
        },
        'circle',
      );

      const data = {
        nodes: [
          {
            id: '7',
            x: 200,
            y: 200,
            size: 40,
            shape: 'circleNode',
            anchorPoints: [
              [1, 0.5],
              [1, 0],
            ],
          },
          {
            id: '8',
            x: 400,
            y: 400,
            size: 40,
            shape: 'circleNode',
            anchorPoints: [
              [0, 0.5],
              [0, 1],
            ],
          },
        ],
        edges: [
          { source: '7', target: '8', shape: 'line-arrow-self', sourceAnchor: 0, targetAnchor: 0 },
        ],
      };

      const graph = new G6.Graph({
        container: 'mountNode',
        width: 500,
        height: 500,
        modes: {
          // 支持的 behavior
          default: ['drag-node'],
        },
      });

      G6.registerEdge('line-arrow', {
        draw(cfg, group) {
          const { startPoint, endPoint } = cfg;
          const keyShape = group.addShape('path', {
            attrs: {
              path: [
                ['M', startPoint.x, startPoint.y],
                ['L', endPoint.x / 3 + (2 / 3) * startPoint.x, startPoint.y],
                ['L', endPoint.x / 3 + (2 / 3) * startPoint.x, endPoint.y],
                ['L', endPoint.x, endPoint.y],
              ],
              stroke: '#BBB',
              lineWidth: 1,
              startArrow: {
                path: 'M 6,0 L -6,-6 L -3,0 L -6,6 Z',
                d: 6,
              },
              endArrow: {
                path: 'M 6,0 L -6,-6 L -3,0 L -6,6 Z',
                d: 6,
              },
              className: 'edge-shape',
            },
          });
          return keyShape;
        },
      });

      G6.registerEdge(
        'line-arrow-self',
        {
          getPath(points) {
            const startPoint = points[0];
            const endPoint = points[1];
            return [
              ['M', startPoint.x, startPoint.y],
              ['L', endPoint.x / 3 + (2 / 3) * startPoint.x, startPoint.y],
              ['L', endPoint.x / 3 + (2 / 3) * startPoint.x, endPoint.y],
              ['L', endPoint.x, endPoint.y],
            ];
          },
          getShapeStyle(cfg) {
            const startPoint = cfg.startPoint;
            const endPoint = cfg.endPoint;
            const controlPoints = this.getControlPoints(cfg);
            let points = [startPoint]; // 添加起始点
            // 添加控制点
            if (controlPoints) {
              points = points.concat(controlPoints);
            }
            // 添加结束点
            points.push(endPoint);
            const path = this.getPath(points);
            const style = G6.Util.mix(
              {},
              G6.Global.defaultEdge.style,
              {
                stroke: '#BBB',
                lineWidth: 1,
                path,
                startArrow: {
                  path: 'M 6,0 L -6,-6 L -3,0 L -6,6 Z',
                  d: 6,
                },
                endArrow: {
                  path: 'M 6,0 L -6,-6 L -3,0 L -6,6 Z',
                  d: 6,
                },
              },
              cfg.style,
            );
            return style;
          },
        },
        'line',
      );

      graph.data(data);
      graph.render();
    </script>
  </body>
</html>
